﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once

#include "GcmpModel.h"
#include "Box3d.h"
#include "VertexStreamPrimitiveType.h"

namespace gcmp
{
    
    /// \brief 批量渲染使用的离散数据集接口
    class GCMP_MODEL_EXPORT IDiscretizedData
    {
    public:
        /// \brief 创建一个离散数据集
        /// \param primitiveType 顶点流原语类型
        /// \param vertices 顶点集合
        /// \param normals 法线集合
        /// \param UVs 纹理集合
        /// \param indices 索引集合
        /// \param gstyleId 样式id
        /// \param materialId 材质id
        /// \return OwnerPtr<IDiscretizedData> 创建出来的离散数据
        static OwnerPtr<IDiscretizedData> Create(VertexStreamPrimitiveType primitiveType, const std::vector<Vector3d>& vertices
            , const std::vector<Vector3d>& normals, const std::vector<Vector2d>& UVs
            , const std::vector<unsigned int>& indices // 如果不带索引，就传入空容器
            , ElementId gstyleId, ElementId materialId);

        /// \brief 创建一个空的离散数据集
        /// \param primitiveType 顶点流原语类型
        /// \param gstyleId 样式id
        /// \param materialId 材质id
        /// \return OwnerPtr<IDiscretizedData> 创建出来的离散数据
        static OwnerPtr<IDiscretizedData> CreateEmpty(VertexStreamPrimitiveType primitiveType, ElementId gstyleId, ElementId materialId);
        
        /// \brief 获取顶点流原语类型
        /// \return 原语类型
        virtual VertexStreamPrimitiveType GetPrimitiveType() const = 0;

        /// \brief 获取顶点集合
        /// \return 顶点集合
        virtual const std::vector<Vector3d>& GetVertices() const = 0;
        
        /// \brief 获取法线坐标集合
        /// \return 法线坐标集合
        virtual const std::vector<Vector3d>& GetNormals() const = 0;

        /// \brief 获取纹理坐标集合
        /// \return 纹理坐标集合
        virtual const std::vector<Vector2d>& GetUVs() const = 0;

        /// \brief 获取索引集合
        /// \return 索引集合
        virtual const std::vector<unsigned int>& GetIndices() const = 0;

        /// \brief 获取图形样式Id
        /// \return 样式ID
        virtual ElementId GetGraphicsStyleId() const = 0; 
        
        /// \brief 获取材质Id
        /// \return 材质ID
        virtual ElementId GetGraphicsMaterialId() const = 0;

        /// \brief 重置顶点集合大小
        /// \param 新的大小
        virtual void ReserveVerticesSize(int size) = 0;

        /// \brief 重置法线集合大小
        /// \param 新的大小
        virtual void ReserveNormalsSize(int size) = 0;

        /// \brief 重置纹理坐标集合大小
        /// \param 新的大小
        virtual void ReserveUVsSize(int size) = 0;

        /// \brief 重置索引集合大小
        /// \param 新的大小
        virtual void ReserveIndicesSize(int size) = 0;

        virtual Box3d GetAABB() const = 0;

        /// \brief 平移操作
        /// \param translateMat 平移矩阵
        /// \return true-操作成功 false-操作失败
        virtual bool Translate(const Matrix4d& translateMat) = 0;

        /// \brief 旋转操作
        /// \param rotMat 旋转矩阵
        /// \return true-操作成功 false-操作失败
        virtual void Rotate(const Matrix4d& rotMat) = 0;

        /// \brief 合并操作
        /// \param vertices 待合并矩阵顶点
        /// \param normals 待合并矩阵顶点
        /// \param UVs 待合并矩阵顶点
        /// \param indices 索引容器
        /// \return true-操作成功 false-操作失败
        virtual bool Merge(const std::vector<Vector3d>& vertices, const std::vector<Vector3d>& normals, const std::vector<Vector2d>& UVs
            , const std::vector<unsigned int>& indices) = 0; // 不带索引就传入空容器

        /// \brief 克隆当前离散数据
        virtual OwnerPtr<IDiscretizedData> Clone() const = 0;
    };

    /// \brief lod精度信息， 默认三个层次
    enum EnLODLevel
    {
        LOD_LEVEL_0,    // 最高精度
        LOD_LEVEL_1,
        LOD_LEVEL_2,
        LOD_LEVEL_COUNT
    };
}

